import { ExclamationCircleOutlined } from '@ant-design/icons';
import {
  Button,
  message,
  Input,
  Card,
  Select,
  Modal,
  Form,
  Radio,
  InputNumber,
} from 'antd';
import React, { useState, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';
import { useIntl, FormattedMessage, history, Link, ConnectProps, connect } from 'umi';
import { PageContainer, FooterToolbar } from '@ant-design/pro-layout';

import { getDeviceList, createTask, getTaskDetail, getUserResource, getUser } from './service';
import { getInference, getModelVersion, getModelVersions } from '../EdgeInference/service';
import format from '@/utils/format.js';
import { nameRule } from '@/utils/rule';
import SelectModel, { model } from '../EdgeInference/components/SelectModel';
import AddEnv, { env } from '../EdgeInference/components/AddEnv';

const Item = Form.Item;
const { Option } = Select;
interface Props extends ConnectProps {}
interface params {
  key: any;
  value: any;
};
interface quota {
  id: number;
  type: string;
  arch: string;
  model?: string;
  computeType?: string;
  series?: string;
  cpuNum: string;
  mem: string;
  creatorName: string;
  createdAt: string;
  num: number; // GPU 和 NPU 的卡数
  alNum: number; // 实际规格可用的总数
}
const NewInference: React.FC<Props> = (props, refs) => {

  const [newForm] = Form.useForm();

  const [devices, setDevices] = useState([]); // 设备类型
  const [options, setOptions] = useState([]); // 设备规格选项
  const [deviceList, setDeviceList] = useState([]);
  const [envs, setEnvs] = useState<env[]>([]);

  const [model, setModel] = useState<model|{}>({});
  // const [modelsGet, setModelsGet] = useState([]);
  // const [source, setSource] = useState('');
  const [specifications, setSpecifications] = useState('');
  const [series, setSeries] = useState(''); // 规格
  const [cpu, setCpu] = useState(''); // CPU
  const [mem, setMem] = useState(''); // 内存
  // const [specificationsNum, setSpecificationsNum] = useState('');

  // const [selectedDevice, setSelectedDevice] = useState(''); //根据当前设备来自动选择灰掉规格

  const [selectNumber, setSelectNumber] = useState(0);
  const [maxSize, setMaxSize] = useState(0);
  const [minSize, setMinSize] = useState(0);
  const [showSelectNumber, setShowSelectNumber] = useState(false); //是否显示设备类型外侧数量选择

  const [groupId, setGroupId] = useState(0);

  const layout = {
    labelCol: { span: 4 },
    wrapperCol: { span: 20 },
  };
  const versionColumns = [
    { title: '模型名称', dataIndex: 'modelName', key: 'modelName' },
    { title: '模型类型', dataIndex: 'modelTask', key: 'modelTask' },

    { title: '版本', dataIndex: 'version', key: 'version' },

    { title: '容器镜像', dataIndex: 'engine', key: 'engine' },
    { title: '数据集', dataIndex: 'datasetName', key: 'datasetName' },
    {
      title: '更新时间',
      dataIndex: 'updateTime',
      key: 'updateTime',
      render: (text: string) => format(text),
    },
  ];
  const { location } = props;
  const { appId, edit } = location?.query as { appId: string, edit: string };
  // let appId = location?.query.appId;
  // const needEdit = edit ? true : false;
  const needEdit = Boolean(edit);

  useEffect(() => {
    console.log('needEdit', needEdit);
    if (needEdit) {
      // 编辑界面，获取信息并初始化
      // 从地址栏中获取推理服务 ID，获取服务信息
      getTaskDetail(appId).then(res => {
        console.log('res', res);
        let info = res.data;

        // setVersion(version_info);
        console.log({ NPU: 'huawei_npu', GPU: 'navida_gpu', CPU: 'cpu' }[info.deviceType]);
        // 初始化基本信息
        newForm.setFieldsValue({
          name: info.name,
          type: info.deviceType,
          // type: { NPU: 'huawei_npu', GPU: 'navida_gpu', CPU: 'cpu' }[info.deviceType],
          describe: info.describe,
          replicas: info.replicas,
        });
        // 初始化模型
        initModel(info.models);
        // setModelsGet(info.models);
        let temp = info.envs;
        if (typeof temp === 'string' && !Object.keys(JSON.parse(temp)).length) return;
        let envObj = JSON.parse(temp);
        let temp_: env[] = [];
        Object.keys(envObj).map((key) => {
          let a: env = { key: key, value: envObj[key] };
          temp_.push(a);
        });
        setEnvs(temp_);
        // setParams(temp_);
      });
    } else {
      console.log('获取用户数据，执行 current');
      // 首先获取用户组 ID
      getUser().then(res => {
        if (res && res.code === 0) {
          const { userGroupId } = res.data;
          console.log(res.data);
          console.log(userGroupId);

          setGroupId(userGroupId);
          // 获取到用户组 ID 后，获取用户组资源列表
          // getUserResource({
          //   userGroupId: groupId
          // }).then(res => {
          //   if (res && res.code === 0) {
          //     console.log(res.data);
          //   }
          // })
        }
      })
      // filterDevice({});
      newForm.setFieldsValue({
        describe: '',
        deviceType: null,
      });
    }
  }, []);

  // 根据选择的设备类型，筛选出合适个规格列表
  function filterDevice(type) {
    let data;
    const device = devices.find(d => d.type === type);
    const memory = Number(device.memory) * 1024 * 1024 * 1024;

    data = {
      type: TYPES.get(type),
      avlNum: device.deviceNum || '',
      cpuNum: device.cpu || '',
      // series: device.series || '', // 添加 series 筛选
      mem: memory || '',
      userGroupId: groupId,
    }
    setMinSize(data.avlNum);
    getDeviceList(data).then((res) => {
      if (res.code == 0) {
        let items = res.data.items;
        // 当设备类型为 GPU，并且模型中的 minifest 设置了 series 时，进行筛选
        // if (device.series.length > 0 && data.type === 'NPU') {

        // 不筛选 GPU、只筛选 NPU
        console.log('筛选series:', device.series);
        if (device.series.length > 0 && data.type === 'NPU') {
          const seriesArr = device.series.split(',');
          items = items.filter(i => seriesArr.includes(i.series));
        }
        if (items.length > 0) {
          setDeviceList(items);
          setSeries(device.series);
          setCpu(device.cpu);
          setMem(device.mem);
          items.sort((a, b) => {
            if (a.mem > b.mem) {
            } else if (a.mem = b.mem) {
              return a.cpuNum - b.cpuNum;
            } else {
              return -1;
            }
          })
          newForm.setFieldsValue({
            deviceType: items[0].id,
          });
          // if (source === 'preset') {
          //   setSpecifications(getSpecifications(items[0]))
          //   setSelectNumber(1)
          // }
        } else {
          message.error('当前用户组无符合该模型的推理设备');
          newForm.setFieldsValue({
            deviceType: null,
            type: '',
          });
        }
      }
    });
  }
  const getSpecifications = (e) => {
    return `${e.key} 丨CPU：${e.cpuNum}核 ${parseInt(Math.ceil(e.mem / (1024 * 1024 * 1024)))}GB 丨${e.arch}`
  }
  function getDeviceType (t: string) {
    return { huawei_npu: 'NPU', nvidia_gpu: 'GPU', cpu: 'CPU' }[t];
  }
  interface item {
    key: string,
    value: any,
  };
  interface information {
    deviceType: string;
    name: string;
    describe: string;
    replicas: string;
    type: string;
  }
  function onFinish (info: information) {
    // const noModel = Object.keys(model).length === 0;
    console.log(Object.keys(model).length === 0);
    if (Object.keys(model).length === 0) {
      message.error('请选择模型');
      return;
    }
    console.log('info', info);
    let env = {};
    envs?.map(e => {
      env[e.key] = e.value;
    });
    const { modelName, id, version, versionId } = model as model;
    const modelNow = { name: modelName, id, version, versionId }
    console.log('setSelectNumber', selectNumber, deviceList);
    let deviceNow = deviceList.filter((e) => e.id == info.deviceType)[0]; //当前选择的设备类型
    console.log(info.deviceType, deviceNow, 'deviceType');
    console.log(info.type);
    console.log(TYPES.get(info.type));
    let data = {
      name: info.name,
      describe: info.describe,
      replicas: info.replicas, //个数
      // deviceType: info.type, //设备类型
      deviceType: TYPES.get(info.type), //设备类型
      envs: env, //环境变量
      resource: {
        arch: 'AMD',
        cpu: deviceNow.cpuNum,
        mem: deviceNow.mem,
        // typeSpec: deviceNow.model,
        typeSpec: deviceNow.computeType,
        // typeSpec: deviceNow.type, // 改为 type
        deviceNum: selectNumber || 1,
      }, //资源device
      models: [modelNow], //模型列表,828设定一个
    };
    console.log(data);
    createTask(data).then((res) => {
      if (res && res.code == 0) {
        message.success('创建成功');
        history.push('/deploy-online/central-inference')
        // window.location.href = './';
      } else {
        message.error('创建失败');
      }
    });
  }

  const getModel = (models: model[]) => {
    const modelOne = models[0];
    // reset the models when there is not a model
    if (!models[0]) {
      newForm.setFieldsValue({
        models: null
      })
      return;
    }
    else{
      newForm.setFieldsValue({
        models: modelOne
      })
    }
    setModel(modelOne || []);
    getInference(modelOne.id, modelOne.versionId).then(res => {
      if (res && res.code === 0) {
        console.log(res.data.modelVersionInference.center.devices);
        const devicesTemp = res.data.modelVersionInference.center.devices;
        console.log('devicesTemp', devicesTemp);
        if (devicesTemp && devicesTemp.length > 0) {
          setDevices(devicesTemp);
        } else {
          message.error('暂无模型相关 manifest');
        }
      }
    })
  };
  const TYPES = new Map([
    ['cpu', 'CPU'],
    ['nvidia_gpu', 'GPU'],
    ['huawei_npu', 'NPU'],
  ]);

  // 初始化模型
  const initModel = (models: model[]) => {
    // 获取模型id 和模型版本
    const model = models[0];
    console.log(model);
    getModelVersion(model.id, model.versionId).then(res => {
      if (res && res.code === 0) {
        console.log(res.code);
        const versionData = res.data.modelVersion;
        const {
          engine,
          modelName,
          id,
          version,
          versionId,
          task,
          field,
          source,
          updatedAt,
        } = versionData;
        setModel({
          engine,
          modelName,
          id,
          version,
          versionId,
          task,
          field,
          source,
          updatedAt,
        })
      }
    })
  }

  useEffect(() => {
    console.log('devices', devices)
    newForm.setFieldsValue({
      type: '',
      deviceType: 0,
    });
    setSpecifications(null);
    setSelectNumber(null);
    console.log(newForm.getFieldValue())
    const types = [...new Set(devices.map(d => d.type))];
    console.log(types);
    const optionsTemp = types.map(t => { return { label: TYPES.get(t), value: t }})
    console.log(optionsTemp);
    setOptions(optionsTemp);
    console.log(types);
  }, [devices])

  return (
    <PageContainer
      title={React.$i18n('Inference.创建推理服务')}
      onBack={() => {
        Modal.confirm({
          centered: true,
          closable: true,
          icon: <ExclamationCircleOutlined />,
          maskClosable: true,
          okType: 'danger',
          okText: '确认',
          cancelText: '取消',
          width: '30%',
          title: <div style={{ fontWeight: 'bold' }}>确定退出么？</div>,
          content: <div>当前页面的数据不会保存</div>,
          onOk: async () => {
            history.push('/deploy-online/central-inference')
            // window.location.href = './';
          },
          cancelButtonProps: {},
          onCancel: () => {},
        });
      }}
      ghost={false}
    >
      {/* <Card bodyStyle={{ padding: ' 16px' }}> */}
      <Card>
        <Form
          {...layout}
          name="basic"
          initialValues={{ remember: true }}
          onFinish={v => onFinish(v)}
          // onFinishFailed={v => onFinishFailed(v)}
          form={newForm}
        >
          <Item
            label="推理服务名称"
            name="name"
            labelAlign='left'
            initialValue={`default-${Math.ceil(Math.random()*1000)}`}
            rules={nameRule()}
          >
            <Input/>
          </Item>

          <Item label="描述" name="describe" labelAlign='left'>
            <Input.TextArea maxLength={200} showCount placeholder='请输入描述，限制 200 字符以内' />
          </Item>

          <Item label="选择模型" name="models" labelAlign='left' rules={[{ required: true }]}>
            <SelectModel getModel={getModel} model={model}></SelectModel>
          </Item>

          <Item label="设备类型" name="type" rules={[{ required: true }]} labelAlign='left'>
            <Radio.Group
              buttonStyle="solid"
              options={options}
              optionType="button"
              onChange={(row) => {
                const selected = newForm.getFieldsValue()['type'];
                setShowSelectNumber(['nvidia_gpu', 'huawei_npu'].includes(selected));
                console.log('当前选中的设备类型:', selected);
                filterDevice(selected);
              }}
            />
          </Item>
          <Item
            label="规格"
            name="deviceType"
            required
            // rules={[{ required: true }]}
            labelAlign='left'
          >
            <Select
              placeholder="请选择规格"
              value={specifications}
              style={{ width: 320 }}
              onChange={(e) => {
                console.log(e);
                setSpecifications(e);
                let device = deviceList.filter((i) => i.id == e)[0];
                let avlNum = device.avlNum;
                newForm.setFieldsValue({
                  deviceType: e,
                });
                setMaxSize(avlNum);
                setSelectNumber(null);
              }}
            >
              {deviceList.map((e: quota, i) => {
                return (
                  <Option value={e.id} key={i}>
                    {e.key} 丨{e.cpuNum}核 {parseInt(Math.ceil(Number(e.mem) / (1024 * 1024 * 1024)))}GB 丨{' '}
                    {e.arch}
                  </Option>
                );
              })}
            </Select>
            {showSelectNumber && (
              <Select style={{ width: 120 }} onChange={setSelectNumber} placeholder='卡数' value={selectNumber}>
                {[...Array(maxSize).keys()].map((e) => {
                  e += 1;
                  return e >= minSize ? (
                    <Option value={e} key={e}>
                      {e}
                    </Option>
                  ): null;
                })}
              </Select>
            )}
            { Boolean(series) && <span>推荐使用 {series}</span>}
            { (Boolean(cpu) || Boolean(mem)) && <span>最小规格 {cpu ? `CPU: ${cpu}核` : ''}{mem ? `内存${mem}G` : ''}</span>}
          </Item>
          <Item
            label="环境变量"
            name="env"
            labelAlign='left'
            // rules={[{ required: true }]}
            tooltip="注入环境变量到容器实例"
          >
            <AddEnv envs={envs} setEnvs={setEnvs}></AddEnv>
          </Item>

          <Item
            label="副本数量"
            name="replicas"
            rules={[{ required: true }]}
            tooltip="设置当前版本模型实例个数"
            labelAlign='left'
          >
            <InputNumber min={1} max={10} />
          </Item>
          <Item label=" " style={{ width: '100%' }} colon={false}>
            <Button type="primary" htmlType="submit">
              提交
            </Button>
          </Item>
        </Form>
      </Card>
    </PageContainer>
  );
}

export default connect()(NewInference);
